
//Copyright 1997-2009 Syrinx Development, Inc.
//This file is part of the Syrinx Web Application Framework (SWAF).
// == BEGIN LICENSE ==
//
// Licensed under the terms of any of the following licenses at your
// choice:
//
//  - GNU General Public License Version 3 or later (the "GPL")
//    http://www.gnu.org/licenses/gpl.html
//
//  - GNU Lesser General Public License Version 3 or later (the "LGPL")
//    http://www.gnu.org/licenses/lgpl.html
//
//  - Mozilla Public License Version 1.1 or later (the "MPL")
//    http://www.mozilla.org/MPL/MPL-1.1.html
//
// == END LICENSE ==
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;

using Swaf;
using Swaf.BizObj;
using Swaf.BizRule;
using Swaf.Container;
using Swaf.Security;

namespace eCom
{
	public class eComPaymentBizRules : Syrinx.BaseBizRules
	{

		public void updateCompanyPaymentTerm(IApplication app, IRuleContext context, Swaf.BGuid.Guid companyId, IBizObj term)
		{
			FlexiMap m = new FlexiMap();
			m.put("companyId", companyId);
			m.put("termId", term.get("id"));
			if (!term.isNew)
				context.RuleGroup.execute(context, "deleteCompanyPaymentTerm", companyId, term.get("id"));

			app.appData.put("DA.eCom.AddCompanyPaymentTerm", m);
		}

		public void deleteCompanyPaymentTerm(IApplication app, IRuleContext context, Swaf.BGuid.Guid companyId, Swaf.BGuid.Guid termId)
		{
			FlexiMap m = new FlexiMap();
			m.put("companyId", companyId);
			m.put("termId", termId);
			app.appData.put("DA.eCom.DeleteCompanyPaymentTerm", m);
		}

		public void updateUserPaymentTerm(IApplication app, IRuleContext context, IBizObj term)
		{
			if (!term.isNew)
				context.RuleGroup.execute(context, "deleteUserPaymentTerm", term.get("userId"), term.get("id"));

			app.appData.put("DA.eCom.AddUserPaymentTerm", term);
		}

		public void deleteUserPaymentTerm(IApplication app, IRuleContext context, Swaf.BGuid.Guid userId, Swaf.BGuid.Guid termId)
		{
			FlexiMap m = new FlexiMap();
			m.put("userId", userId);
			m.put("termId", termId);
			app.appData.put("DA.eCom.DeleteUserPaymentTerm", m);
		}

		public IBizObjList getAllUsersPaymentTerms(IApplication app, IRuleContext context, Swaf.BGuid.Guid companyId)
		{
			FlexiMap m = new FlexiMap();
			m.put("companyId", companyId);
			IBizObjList terms = app.appData.get("DA.eCom.GetAllUsersPaymentTerms", m) as IBizObjList;
			return terms;
		}


		public IBizObjList getUserPaymentTerms(IApplication app, IRuleContext context, Swaf.BGuid.Guid userId, IBizObj salesOrder)
		{
			IBizObjList terms = null;

			bool hasProductsThatCost = false;
			foreach (IBizObj orderItem in (IBizObjList)salesOrder.get("items"))
				if ((decimal)orderItem.get("product.sellPrice") > 0)
				{
					hasProductsThatCost = true;
					break;
				}

			if (!hasProductsThatCost)
				terms = app.bizObjMgr.createList("eComPaymentTerm");
			else
			{
				FlexiMap m = new FlexiMap();
				m.put("userId", userId);
				terms = app.appData.get("DA.eCom.GetUserPaymentTerms", m) as IBizObjList;

				if (terms != null || terms.numElements == 0)
				{
					m.put("userId", ActiveCompany.get("anonymousId"));
					terms = app.appData.get("DA.eCom.GetUserPaymentTerms", m) as IBizObjList;
				}

				INameAddressSupport info = new FlexiMap();
				info.put("parentId", "sys_eComPaymentMethods");
				info.put("listDetailLevel", DetailLevel.fullDetails);
				IBizObj criteria = null;
				IResults rc = context.RuleGroup.execute(context, "getArticles", info, criteria);
				IBizObjList paymentTermArticles = rc.CallResults as IBizObjList;
				if (paymentTermArticles != null)
					foreach (IBizObj t in terms)
						foreach (IBizObj a in paymentTermArticles)
							if (string.Compare((string)a.get("uniqueTitle"), "sys_" + t.type.Name) == 0)
							{
								t.put("article", a);
								break;
							}
			}
			return terms;
		}

		public IBizObj updateSalesOrderPaymentTermInfo(IApplication app, IRuleContext context,string returnUrl, IBizObj order, IBizObj paymentTerm)
		{
			string ruleName = paymentTerm.type.Name;
			ruleName = new StringBuilder(50).Append("update").Append(ruleName).Append("SalesOrderPayment").ToString();				
			IResults rc = context.RuleGroup.execute(context, ruleName, returnUrl, order, paymentTerm);
			//TODO: Process payment failures.
			return rc.CallResults as IBizObj;
		}

		public IBizObj updateeComCreditCardPaymentInfoSalesOrderPayment
			(IApplication app, IRuleContext context, string returnUrl, IBizObj salesOrder, IBizObj paymentTerm)
		{
			IBizObj controlInfo = app.bizObjMgr.create("eComPaymentControlInfo");
			DateTime expireDate = (DateTime)paymentTerm.get("expireDate");
			if (expireDate == null || expireDate == DateTime.MinValue)
				paymentTerm.put("expireDate", DateTime.Now.ToUniversalTime().Date);
			FlexiMap m = new FlexiMap();
			m.put("order", salesOrder);
			m.put("payment", paymentTerm);
			
			app.appData.put("DA.eCom.DeleteSalesOrderPaymentInfo", m);
			app.appData.put("DA.eCom.AddSalesOrderPaymentInfo", m);
			app.appData.put("DA.eCom.UpdateSalesOrderPaymentTermsId", m);

			controlInfo.put("paymentSuccessful", true);
			return controlInfo;
		}

		public IBizObj getSalesOrderPaymentTermDetails(IApplication app, IRuleContext context, object resultValue, object[] inputParams)
		{
			IBizObj salesOrder = resultValue as IBizObj;
			if (salesOrder != null)
			{

				IBizObj termBasics = app.appData.get("DA.eCom.GetPaymentTerm", salesOrder) as IBizObj;
				if (termBasics != null)
				{
					string bizObjType = termBasics.get("bizObjType").ToString();
					string ruleName = new StringBuilder(50).Append("get").Append(bizObjType).Append("PaymentDetails").ToString();

					IResults rc = context.RuleGroup.execute(context, ruleName, salesOrder.get("id"));

					IBizObj termDetails = rc.CallResults as IBizObj;
					if (termDetails != null)
						salesOrder.put("paymentMethod", termDetails);
					else
						salesOrder.put("paymentMethod", termBasics);
				}
			}
			return salesOrder;
		}

		public IBizObj geteComCreditCardPaymentInfoPaymentDetails(IApplication app, IRuleContext context, Swaf.BGuid.Guid salesOrderId)
		{
			FlexiMap m = new FlexiMap();
			m.put("id", salesOrderId);
			IBizObj termDetails = app.appData.get("DA.eCom.GetBasicCreditCardPaymentInfo", m) as IBizObj;
			return termDetails;
		}
	}
}
